/**
 * Copyright (c) 2020 Coder League
 * All rights reserved.
 *
 * File：AreaDaoImpl.java
 * History:
 *         2020年12月21日: Initially created, Chrise.
 */
package club.coderleague.cfss.dao.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import club.coderleague.cfss.dao.extension.AreaDaoExtension;
import club.coderleague.cfss.domain.entities.Areas;
import club.coderleague.cfss.domain.enums.EntityState;
import club.coderleague.data.jpa.id.support.SnowflakeV4;
import club.coderleague.data.jpa.repository.support.AbstractDataRepositoryExtension;

/**
 * 区域数据访问对象实现。
 * @author Chrise
 */
public class AreaDaoImpl extends AbstractDataRepositoryExtension<Areas, Long, SnowflakeV4> implements AreaDaoExtension {
	/**
	 * @see club.coderleague.cfss.dao.extension.AreaDaoExtension#findAllByParamsMap(boolean, java.lang.String)
	 */
	@Override
	public List<Areas> findAllByParamsMap(boolean isrecycle, String keyword) {
		StringBuilder jpqlBuilder = new StringBuilder("from Areas a where a.entitystate = :entitystate");
		Map<String, Object> params = new HashMap<>();
		params.put("entitystate", isrecycle ? EntityState.INVALID.getValue() : EntityState.VALID.getValue());
		// 关键字
		if (StringUtils.isNotBlank(keyword)) {
			jpqlBuilder.append(" and (a.areaname like :keyword or a.areacode like :keyword)");
			params.put("keyword", "%" + keyword + "%");
		}
		jpqlBuilder.append(" order by a.areacode");
		return super.queryEntityList(jpqlBuilder.toString(), params);
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.AreaDaoExtension#findAllMap()
	 */
	@Override
	public List<Map<String, Object>> findAllMap() {
		String sql = "select a.entityid as entityid, a.areaname as areaname, a.parentarea as parentarea from areas a where a.entitystate = ?0 order by a.areacode";
		return super.queryMapListBySql(sql, EntityState.VALID.getValue());
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.AreaDaoExtension#existsByAreanameAndParentareaNotEntityid(java.lang.String, java.lang.String, java.lang.Long, java.lang.Long)
	 */
	@Override
	public boolean existsByAreanameAndParentareaNotEntityid(String areaname, String areacode, Long parentarea, Long entityid) {
		StringBuilder sqlBuilder = new StringBuilder("select count(*) from areas a where a.entitystate = :validstate and (a.areaname = :areaname or a.areacode = :areacode)");
		Map<String, Object> params = new HashMap<>();
		params.put("validstate", EntityState.VALID.getValue());
		params.put("areaname", areaname);
		params.put("areacode", areacode);
		if (parentarea != null) {
			sqlBuilder.append(" and a.parentarea = :parentarea");
			params.put("parentarea", parentarea);
		} else {
			sqlBuilder.append(" and a.parentarea is null");
		}
		if (entityid != null) {
			sqlBuilder.append(" and a.entityid != :entityid");
			params.put("entityid", entityid);
		}
		return super.queryLongBySql(sqlBuilder.toString(), params) > 0;
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.AreaDaoExtension#queryIdByCode(java.lang.String)
	 */
	@Override
	public Long queryIdByCode(String areacode) {
		String jpql = "select entityid from Areas where areacode = ?0";
		return super.queryLong(jpql, areacode);
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.AreaDaoExtension#findMapByEntityid(java.lang.Long)
	 */
	@Override
	public Map<String, Object> findMapByEntityid(Long entityid) {
		String sql = "select a.entityid as entityid, a.areaname as areaname, a.areacode as areacode, a.areadesc as areadesc, aa.areaname as parentareaname"
				+ " from areas a left join areas aa on aa.entityid = a.parentarea and aa.entitystate = ?1 where a.entityid = ?0";
		return super.queryMapBySql(sql, entityid, EntityState.VALID.getValue());
	}
	
	/**
	 * @see club.coderleague.cfss.dao.extension.AreaDaoExtension#getAreasForMobileSelect(java.lang.Long)
	 */
	@Override
	public List<Map<String, Object>> getAreasForMobileSelect(Long parent) {
		Map<String, Object> params = new HashMap<>();
		params.put("entitystate", EntityState.VALID.getValue());
		
		String sql = "select entityid as value, areaname as label from areas where entitystate = :entitystate";
		if (parent == null) sql += " and parentarea is null";
		else {
			sql += " and parentarea = :parentarea";
			params.put("parentarea", parent);
		}
		sql += " order by areacode";
		
		return super.queryMapListBySql(sql, params);
	}
}
